/***** BEGIN LICENSE BLOCK *****
Copyright the original author Andy Shaules ( bowljoman AT hotmail DOT com) thebitstream.com
Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
	http://www.mozilla.org/MPL/MPL-1.1.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

# ***** END LICENSE BLOCK *****/
package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.NetStatusEvent;
	import flash.ui.Keyboard;
	import flash.utils.setTimeout;
	
	import sandy.core.Scene3D;
	import sandy.core.scenegraph.Camera3D;
	import sandy.core.scenegraph.Group;
	import sandy.primitive.Sphere;
	import sandy.redSandy.IRedSandy;
	import sandy.redSandy.RedSandy;
	import sandy.redSandy.SharedTransformGroup;
	
	[SWF(width="400",height="400")]
	/**
	 * 
	 * @author Andy Shaules
	 * 
	 */	
	public class Redsandy extends Sprite implements IRedSandy
	{
		private var c:RedSandy;
		private var world:Scene3D;
		private var camera:Camera3D;
		private var group:Group;	
		private var keys:Object=new Object();
		public var clientData:Object=new Object ();
		
		public function Redsandy()
		{	//crank it up
			stage.frameRate=40;
		
			// make the connection.
			c=new RedSandy();			
			c.client=this;
			c.netConnectionEvents.addEventListener(NetStatusEvent.NET_STATUS,onStatExample);
			c.connect("rtmp://localhost:1935/sandy/room","hello","sandy");
			
			
			
			// make out sandy world
			camera = new Camera3D(400,400);
        	group=new Group();
        	world =new Scene3D('avatar'+Math.random(),this,camera, group);
        	world.camera.near=.01; 
			world.rectClipping=false;
			camera.z=-300;

			// add the example application funcitons
			stage.addEventListener(KeyboardEvent.KEY_DOWN,onKey);
			stage.addEventListener(KeyboardEvent.KEY_UP,onKey);
			addEventListener(Event.ENTER_FRAME,onFrame);
		
		}
		
		/**
		 * Server initiated call to retrieve this instance's cooridinates. 
		 * It is called at the server-granularity setting, or as fast as your network and application can respond, whichever is greator.
		 * It is a timely moment to process user input.  
		 */
		public function onInput(myPosition:SharedTransformGroup):void
		{
			
			if(isDown(Keyboard.UP))
			{
				myPosition.m_nAccellVelocityY=myPosition.m_nAccellVelocityY-1;
			}
			else if(isDown(Keyboard.DOWN))
			{
				myPosition.m_nAccellVelocityY=myPosition.m_nAccellVelocityY+1;
			}else
			{
			myPosition.m_nAccellVelocityY=	(myPosition.m_nAccellVelocityY>0)? myPosition.m_nAccellVelocityY-1 :myPosition.m_nAccellVelocityY+1;
			}
			if(isDown(Keyboard.LEFT))
			{
				myPosition.m_nAccellRotateVelocityY=myPosition.m_nAccellRotateVelocityY-1;
			}else
			if(isDown(Keyboard.RIGHT))
			{				
				myPosition.m_nAccellRotateVelocityY=myPosition.m_nAccellRotateVelocityY+1;
			}else
			{
				myPosition.m_nAccellRotateVelocityY=	(myPosition.m_nAccellRotateVelocityY>0)? myPosition.m_nAccellRotateVelocityY-1 :myPosition.m_nAccellRotateVelocityY+1;
			}
								
		}
		
		/**
		 * Called from another user's sendEvent function call.
		 * @param obj
		 * 
		 */		
		public function onEvent(obj:Object):void
		{
			trace(obj.value)
		}
		
		/**
		 * Called when user joins the room.
		 */
		public function onJoined(obj:Object,group:SharedTransformGroup):void
		{
			trace("joined by "+obj.id);
			
			var b:Sphere=new Sphere('sphere'+obj.id,25);
			group.addChild(b);
			world.root.addChild(group);
		}
		
		/**
		 * Called when user leaves the room.
		 */
		public function onLeave(obj:Object):void
		{
			world.root.removeChildByName(obj.id);
		}
		
		/**
		 * Here is this instance's SharedTransformGroup
		 * */
		public function onCreated(obj:SharedTransformGroup):void
		{	
			clientData.id=obj.name;
			var b:Sphere=new Sphere('sphere',25);
			obj.addChild(b);
			world.root.addChild(obj);
		}
		/**
		 * If using the velocity properties of the SharedTransformGroup, 
		 * you must call 'SharedTransformGroup.initiateRender()'.
		 * Test App implementation 
		 * @param e
		 * 
		 */		
		private function onFrame(e:Event):void
		{
			SharedTransformGroup.initiateRender();
			world.render();			
		}
		/**
		 * Test App implementation 
		 * @param ns
		 * 
		 */				
		private function onStatExample(ns:NetStatusEvent):void
		{
			trace(ns.info.code);
			if(ns.info.code=='NetConnection.Connect.Success')
			{	
				// Run some tests.
				
				// set a single property
				setTimeout(setPropertyExample,4000);
				
				// retrieve it
				setTimeout(getPropertyExample,5000);
				
				// get another user property (in this test case, our own.)
				setTimeout(getUserPropertyExample,6000);
				
				// get all my properties
				setTimeout(getAllPropertiesExample,7000);
				
				// Send to other clients. This instance will not get this event.
				setTimeout(sendEventExample,8000);
			}	
		}
		
		/**
		 * Test App implementation
		 * 
		 */		
		public function setPropertyExample():void
		{
			c.setProperty("test","success",onResult);
			function onResult(obj:Object):void
			{
				trace(obj);					
			}			
		}
		
		/**
		 * Test App implementation 
		 * 
		 */		
		public function getPropertyExample():void
		{
			c.getProperty("test",onResult);
			function onResult(obj:Object):void
			{
					trace(obj);
					clientData["test"]=obj;							
			}			
		}
		
		/**
		 * Test App implementation 
		 * 
		 */				
		public function getAllPropertiesExample():void
		{
				c.getAllProperties(onResult2);
				function onResult2(obj2:Object):void
				{
					clientData=obj2;
					trace(obj2.test);						
				}			
		}
		
		/**
		 * Test App implementation 
		 * 
		 */		
		public function getUserPropertyExample():void
		{
			c.getUserProperty(clientData.id,"test",onResult);
			function onResult(obj:Object):void
			{
					trace(obj);						
			}			
		}
		
		/**
		 * Test App implementation 
		 * 
		 */				
		public function sendEventExample():void
		{
			
			c.sendEvent({type:"event.test", value:"success"});		
		}
		
		/**
		 * Test App implementation 
		 * @param ke
		 * 
		 */				
		private function onKey(ke:KeyboardEvent):void
		{
			switch(ke.type)
			{
				case KeyboardEvent.KEY_UP:				
				
				keys[ke.keyCode.toString()]="up";
				break;
				case KeyboardEvent.KEY_DOWN:
				
				keys[ke.keyCode.toString()]="down";
				break;
			}			
		}
		
		/**
		 * Test App implementation 
		 * @param val
		 * @return 
		 * 
		 */		
		public function isDown(val:uint):Boolean
		{
			if(keys[val]=="down")
			{
				return true;
			}
			return false;
		}
		


	}
}
